package com.hibase.core.i18n.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.hibase.common.constant.RedisKeyConstant;
import com.hibase.common.entity.User;
import com.hibase.common.util.UserContext;
import com.hibase.core.i18n.constant.I18nConstant;
import com.hibase.core.i18n.entity.MdsMessageSource;
import com.hibase.core.i18n.entity.vo.MdsMessageSourceImportVO;
import com.hibase.core.i18n.entity.vo.MdsMessageSourceSearchVO;
import com.hibase.core.i18n.mapper.MdsMessageSourceMapper;
import com.hibase.core.i18n.service.MdsMessageSourceService;
import com.hibase.core.mybatis.service.BaseServiceImpl;
import com.hibase.core.redis.util.RedisUtil;
import com.hibase.core.web.excel.ExcelParse;
import com.hibase.common.exception.HibaseAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 国际化信息表 服务实现类
 * </p>
 *
 * @author chenfeng
 * @since 2021-03-24
 */
@Slf4j
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MdsMessageSourceServiceImpl extends BaseServiceImpl<MdsMessageSourceMapper, MdsMessageSource> implements MdsMessageSourceService {


    @Autowired
    private RedisUtil redisUtil;
    /**
     * 查询国际化信息表列表
     */
    @Override
    public PageInfo<MdsMessageSource> selectMdsMessageSourceList(MdsMessageSourceSearchVO searchVO) {

        return super.page(searchVO, new QueryWrapper<MdsMessageSource>()
                .like(StrUtil.isNotBlank(searchVO.getKeyword()),"keyword",searchVO.getKeyword())
                .eq(StrUtil.isNotBlank(searchVO.getCountry()),"country",searchVO.getCountry())
                .like(StrUtil.isNotBlank(searchVO.getCode()),"code",searchVO.getCode())
                .like(StrUtil.isNotBlank(searchVO.getName()),"name",searchVO.getName())
                .like(StrUtil.isNotBlank(searchVO.getKeyWord()),"code",searchVO.getKeyWord())
        );
    }

    /**
     * 改变国际化信息表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMdsMessageSource(MdsMessageSource entity) {

        super.store(entity);
    }

    /**
     * 查询国际化信息表详情
     */
    @Override
    public MdsMessageSource viewMdsMessageSource(String id) {

        MdsMessageSource entity = super.getById(id, true);

        return entity;
    }

    /**
     * 删除国际化信息表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMdsMessageSource(String id) {

        super.deleteBy(id);
    }

    @Override
    public Map<String,String> selectList(MdsMessageSourceSearchVO searchVO) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String header = request.getHeader(I18nConstant.HEADER);
        if(StrUtil.isBlank(header)){
            header = I18nConstant.DEFAULT_HEADER;
        }
        //设置用户默认语言
        //更换绑定仓库以后需要更新 缓存中的用户信息
        User olduser = UserContext.get();
        HibaseAssert.isTrue(olduser !=null,"未查询到用户信息！");
        olduser.setLanguage(header);
        // 重新缓存用户信息
        UserContext.set(olduser);
        List<MdsMessageSource> list = super.list(new QueryWrapper<MdsMessageSource>()
                .eq("country", header)
                .eq("be_active", Boolean.TRUE));
        return list.stream().collect(Collectors.toMap(MdsMessageSource::getCode,MdsMessageSource::getName,(o1,o2)-> o1));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enableMdsMessageSource(List<String> ids) {
        Collection<MdsMessageSource> messageSources = super.listByIds(ids);
        messageSources.forEach(source ->{
            HibaseAssert.isFalse(source.getBeActive(),"请勿重复操作");
            source.setBeActive(Boolean.TRUE);
        });
        super.storeBatch(messageSources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableMdsMessageSource(List<String> ids) {
        Collection<MdsMessageSource> messageSources = super.listByIds(ids);
        messageSources.forEach(source ->{
            HibaseAssert.isTrue(source.getBeActive(),"请勿重复操作");
            source.setBeActive(Boolean.FALSE);
        });
        super.storeBatch(messageSources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importMdsMessageSource(MultipartFile multipartFile, String country, String type) throws IOException {
        // 解析记录表格文件
        List<MdsMessageSourceImportVO> importVO = new ExcelParse<MdsMessageSourceImportVO>().parseExcel(MdsMessageSourceImportVO.class, multipartFile.getInputStream());
        log.info("[国际化导入] 列表数: {}",importVO.size());
        List<MdsMessageSource> list =new ArrayList<>(importVO.size());
        IntStream.range(0,importVO.size()).forEach(i ->{
            MdsMessageSourceImportVO vo = importVO.get(i);
            HibaseAssert.notNull(vo.getKeyword(),"{}行关键值不能为空",i+2);
            HibaseAssert.notNull(vo.getCode(),"{}行国际化代码不能为空",i+2);
            HibaseAssert.notNull(vo.getName(),"{}行国际化值不能为空",i+2);
            MdsMessageSource source = BeanUtil.copyProperties(vo, MdsMessageSource.class);
            source.setCountry(country);
            source.setType(type);
            list.add(source);
        });
        super.storeBatch(list);
    }

    @Override
    public void refresh() {
        List<MdsMessageSource> messageSourceList = this.list();
        Map<String, List<MdsMessageSource>> map = messageSourceList.stream().collect(Collectors.groupingBy(MdsMessageSource::getCountry));
        redisUtil.hPutAll(RedisKeyConstant.CACHE_MESSAGE_SOURCE_KEY,map);
    }
}
